#include "cutscene.h"
#include <QPainter>
#include <qmath.h>

bool CutSceneManager::initialized           = false;
CutSceneManager* CutSceneManager::csmanager = 0;
QGraphicsScene* CutSceneManager::scene      = 0;

CutSceneManager::CutSceneManager( QObject *parent )
    :QObject( parent )
{
}

void CutSceneManager::initialize( QGraphicsScene * s )
{
    if( initialized )
    {
        qDebug() << "Warning: you shall only initialize this class once!";
    }
    csmanager = new CutSceneManager( s );
    initialized = true;
    scene = s;
}

GhostingGraphicsObject * CutSceneManager::getGhosting()
{
    GhostingGraphicsObject * item = new GhostingGraphicsObject;
    scene->addItem(item);
    return item;
}

GhostingGraphicsObject::GhostingGraphicsObject(QGraphicsItem *parent) :
    QGraphicsObject(parent), dur_show( 500 ), dur_hide( 500 )
{
    colors[0] = QColor( COLOR0 );
    colors[1] = QColor( COLOR1 );
    colors[2] = QColor( COLOR2 );
    colors[3] = QColor( COLOR3 );
    colors[4] = QColor( COLOR4 );

    timer = new QTimer( this );
    timer->setInterval( 10 );
    connect( timer, SIGNAL(timeout()), this, SLOT(updateAnimation()) );
    init_dist = 0;

    hide_anim = new QPropertyAnimation( this, "opacity", this );
    hide_anim->setDuration( dur_hide );
    hide_anim->setStartValue( 1 );
    hide_anim->setEndValue( 0 );
    connect( hide_anim, SIGNAL(finished()), this, SLOT(deleteLater()));
    dynamicOpacity = true;
    opac = 0;
}

void GhostingGraphicsObject::setPixmap(QString pmap, bool colorized)
{
    pixmap = QPixmap( pmap );
    offset = QPointF( -pixmap.width()/2, -pixmap.height()/2 );

    for( int i = 0; i < 5; i ++ )
    {
        if( colorized )
        {
            mypixmap[i] = QPixmap( pixmap.width(), pixmap.height() );
            mypixmap[i].fill( colors[i] );
            mypixmap[i].setAlphaChannel( pixmap.alphaChannel() );
        }
        else
        {
            mypixmap[i] = QPixmap( pmap );
        }
        poses[i] = QPointF( 0, 0 );
    }
    poses[5] = QPointF( 0, 0 );
    poses[6] = QPointF( 0, 0 );
}

void GhostingGraphicsObject::setStartEnd(QPointF p0, QPointF p1, bool dynamicOpacity)
{
    pos_start = p0;
    pos_end   = p1;
    poses[6]  = p1;
    for( int i = 0; i < 6; i ++ )
    {
        poses[i] = p0;
    }
    init_dist = ( poses[6] - poses[0] ).manhattanLength();
    setOpacity( 1 );
}

void GhostingGraphicsObject::updateAnimation()
{
    if( ( poses[6] - poses[0] ).manhattanLength() < 5  )
    {
        timer->stop();
        emit ready();
        QTimer::singleShot( dur_show, hide_anim, SLOT(start()) );
    }

    for( int i = 6; i > 0; i -- )
    {
        poses[i-1] += ( poses[i] - poses[i-1] ) * 0.1;
    }
    opac = 1 - qPow( ( poses[6] - poses[0] ).manhattanLength()  / init_dist, 5 );
    if( opac > 0.6 )
    {
        qreal ux, uy, uw, uh;
        ux = ( poses[6].x() < poses[0].x() ? poses[6].x() : poses[0].x() ) - pixmap.width()/2 - 50;
        uy = ( poses[6].y() < poses[0].y() ? poses[6].y() : poses[0].y() ) - pixmap.height()/2 - 50;
        uw = qAbs( poses[6].x() - poses[0].x() ) + pixmap.width() + 100;
        uh = qAbs( poses[6].y() - poses[0].y() ) + pixmap.height() + 100;
        update( ux, uy, uw, uh );
    }
    else
    {
        update();
    }
}

void GhostingGraphicsObject::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    qreal ostep = 1;
    opac *= this->opacity();
    if( dynamicOpacity )
        ostep = 0.1;
    for( int i = -3; i < 2; i ++ )
    {
        painter->setOpacity( ostep * ( i + 5 ) * opac );
        painter->drawPixmap( poses[i+3] + offset, mypixmap[i+3] );
    }
    painter->setOpacity( opac );
    painter->drawPixmap( poses[5] + offset, pixmap );
}

void GhostingGraphicsObject::animate()
{
    update();
    setStartEnd( QPointF( -width, 0 ), QPointF( 200, 0 ) );
    timer->start();
}

//void GhostingGraphicsObject::mousePressEvent(QGraphicsSceneMouseEvent * event)
//{
//    setStartEnd( QPointF( -width, 0 ), event->pos() );
//    animate();
//}
